--[[
Lua 中实现面向对象
  支持创建对象
  支持构造函数，且从父类到子类依次调用
  支持 inherent 和 override
参考 https://blog.codingnow.com/2006/06/oo_lua.html
]]

local _vtable_map = {}

return function(super)
    local class_type = {}
    
    local function new_obj(...)
        local obj = {}
        do
            local create
            function create(cls, ...)
                if cls.super then
                    create(cls.super, ...)
                end
                if cls.ctor then
                    cls.ctor(obj, ...)
                end
            end
            create(class_type, ...)
        end

        setmetatable(obj, class_type._mt)
        return obj
    end

    class_type.ctor = false
    class_type.super = super or false
    class_type.new = new_obj
    
    local vtbl = {} -- 存放 ctor 之外的成员函数
    _vtable_map[class_type] = vtbl

    class_type._mt = {__index = vtbl}

    setmetatable(class_type, {
        __newindex = function(_, k, v)
            vtbl[k] = v
        end,
    })

    if super then
        setmetatable(vtbl, {
            __index = function(_, k)
                local val = _vtable_map[super][k]
                vtbl[k] = val
                return val
            end
        })
    end

    return class_type
end

